<?php

namespace App\Services;

use App\DTO\Airport;
use Illuminate\Support\Collection;

/**
 * Provides a service for searching airports using a search index.
 */
readonly class AirportsSearchService implements SearchServiceInterface
{
    /**
     * @var SearchIndexServiceInterface
     *
     * The search index service to be used for executing search queries.
     */
    private SearchIndexServiceInterface $searchService;

    /**
     * Create a new AirportsSearchService instance.
     *
     * @param SearchIndexServiceInterface $searchService The search index service to be used for searching.
     */
    public function __construct(SearchIndexServiceInterface $searchService)
    {
        $this->searchService = $searchService;
    }

    /**
     * Perform a search for airports based on the given query and return the results as a collection.
     *
     * @param string $query The query to search for.
     * @return Collection A collection of Airport models representing the search results.
     */
    public function search(string $query): Collection
    {
        $params = [
            'query' => [
                'multi_match' => [
                    'query' => $query,
                    'fields' => ['code', 'country', 'cityName.ru', 'cityName.en'],
                    'fuzziness' => 'AUTO'
                ]
            ]
        ];
        $searchResults = $this->searchService->search('airports', $params);

        return collect($searchResults)->map(fn($item) => $this->mapToAirport($item['_source']));
    }

    /**
     * Map the given data to an Airport model.
     *
     * @param array $body The data to map to the Airport model.
     * @return Airport The created Airport model.
     */
    private function mapToAirport(array $body): Airport
    {
        return new Airport(
            code: $body['code'] ?? null,
            cityName: $body['cityName'] ?? null,
            country: $body['country'] ?? null,
            area: $body['area'] ?? null,
            timezone: $body['timezone'] ?? null,
            lat: $body['lat'] ?? null,
            lng: $body['lng'] ?? null,
        );
    }
}
